package org.gikolet.ch2.android.viewer;

import java.io.IOException;

import org.gikolet.ch2.android.R;
import org.gikolet.ch2.android.widget.BoardsAdapter;
import org.gikolet.ch2.android.widget.DialogProgressMonitor;
import org.gikolet.ch2.data.Board;
import org.gikolet.ch2.logic.BoardsLogic;
import org.gikolet.ch2.logic.Ch2Exception;
import org.gikolet.ch2.logic.NotModifiedException;

import roboguice.inject.ContextScoped;
import android.app.AlertDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.ExpandableListView;
import android.widget.Toast;
import android.widget.ExpandableListView.OnChildClickListener;

import com.google.inject.Inject;

@ContextScoped
public class BoardsViewer extends Ch2Viewer {

	private static final int MENU_GROUP_BOARD = 0;
	private static final int MENU_OPEN_BOARD = 1;
	private static final int MENU_OPEN_BOARD_CACHE = 2;

	private static final int MENU_BOARDS_UPDATE = 0;
	private static final int MENU_SEARCH_ALL_BOARDS = 1;

	private ExpandableListView boardListView;

	@Inject
	private BoardsAdapter boardsAdapter;

	@Inject
	private BoardsLogic boardsLogic;

	@Inject
	private ThreadHeadersViewer threadHeaderListViewer;

	@Inject
	private Context context;

	public BoardsViewer() {
	}

	@Override
	public void createView(ViewGroup parent) {

		super.createView(parent);

		this.boardListView = new ExpandableListView(parent.getContext());

		this.boardListView.setAdapter(boardsAdapter);
		this.boardListView.setOnChildClickListener(new OnChildClickListener() {

			public boolean onChildClick(ExpandableListView expandablelistview,
					View view, int i, int j, long l) {
				Board board = (Board) boardsAdapter.getChild(i, j);

				threadHeaderListViewer.load(board, false);

				return true;
			}
		});

		registerForContextMenu(this.boardListView);
		parent.addView(this.boardListView);
	}

	public boolean createMenu(Menu menu) {
		// 板一覧更新メニューの追加
		MenuItem updateBoardListMenu = menu.add(0, MENU_BOARDS_UPDATE, 0,
				R.string.update_board_list);
		MenuItem allBoardsSearchMenu = menu.add(0, MENU_SEARCH_ALL_BOARDS, 0,
				R.string.MENU_SEARCH_ALL_BOARDS);

		updateBoardListMenu.setIcon(android.R.drawable.ic_menu_rotate);
		allBoardsSearchMenu.setIcon(android.R.drawable.ic_menu_search);

		super.createMenu(menu);

		return true;
	}

	@Override
	public void createContextMenu(ContextMenu menu, View view,
			ContextMenuInfo menuInfo) {

		if (menuInfo instanceof ExpandableListView.ExpandableListContextMenuInfo) {
			ExpandableListView.ExpandableListContextMenuInfo itemInfo = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo;

			if (ExpandableListView
					.getPackedPositionType(itemInfo.packedPosition) == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {

				menu.add(MENU_GROUP_BOARD, MENU_OPEN_BOARD, 0,
						R.string.OPEN_BOARD);
				menu.add(MENU_GROUP_BOARD, MENU_OPEN_BOARD_CACHE, 1,
						R.string.OPEN_BOARD_CACHE);
			}
		}
	}

	public boolean onMenuItemSelected(MenuItem item) {
		if (super.onMenuItemSelected(item)) {
			return true;
		}
		switch (item.getItemId()) {

		case MENU_BOARDS_UPDATE:
			updateBoardList();
			return true;

		case MENU_SEARCH_ALL_BOARDS:
			searchAllBoards();
			return true;
		default:
			return false;
		}
	}

	private void searchAllBoards() {
		new AlertDialog.Builder(this.context).setTitle("全板検索")
				.setMessage("未実装").setPositiveButton("OK", null).show();
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case MENU_OPEN_BOARD: {
			Board board = getBoard(item);
			this.threadHeaderListViewer.load(board, false);
			return true;
		}
		case MENU_OPEN_BOARD_CACHE: {
			Board board = getBoard(item);
			this.threadHeaderListViewer.load(board, true);
			return true;
		}
		}

		return false;
	}

	private Board getBoard(MenuItem item) {
		ContextMenuInfo menuInfo = item.getMenuInfo();
		if (menuInfo instanceof ExpandableListView.ExpandableListContextMenuInfo) {
			ExpandableListView.ExpandableListContextMenuInfo itemInfo = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo;

			if (ExpandableListView
					.getPackedPositionType(itemInfo.packedPosition) == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {

				int groupPos = ExpandableListView
						.getPackedPositionGroup(itemInfo.packedPosition);
				int childPos = ExpandableListView
						.getPackedPositionChild(itemInfo.packedPosition);

				return this.boardsAdapter.getChild(groupPos, childPos);
			}
		}
		return null;
	}

	class UpdateTask extends AsyncTask<String, Integer, Ch2Exception> {

		DialogProgressMonitor progressDialog;

		@Override
		protected Ch2Exception doInBackground(String... params) {

			try {
				boardsLogic.update(true, progressDialog);

				return null;

			} catch (Ch2Exception e) {
				return e;

			} catch (IOException e) {
				return new Ch2Exception(e);

			} catch (InterruptedException e) {
				// キャンセルされた場合
				throw new Ch2Exception(e);
			}
		}

		@Override
		protected void onPreExecute() {
			progressDialog = new DialogProgressMonitor(
					BoardsViewer.this.boardListView.getContext(), "板一覧の更新");
		}

		@Override
		protected void onPostExecute(Ch2Exception result) {
			if (result != null) {
				String errMsg;
				if (result instanceof NotModifiedException) {
					// 更新無し
					errMsg = "更新はありませんでした";
				} else {
					result.printStackTrace();
					errMsg = "原因不明のエラーです";
				}
				Toast.makeText(context, errMsg, 0).show();

				return;
			}

			boardsAdapter.notifyDataSetInvalidated();
		}
	}

	public void updateBoardList() {
		UpdateTask task = new UpdateTask();

		task.execute();

		requestView();
	}

	@Override
	public void setFocus() {
		this.boardListView.requestFocus();
	}
}
